<?php
// +----------------------------------------------------------------------
// | INPHP
// | Copyright (c) 2023 https://inphp.cc All rights reserved.
// | Author: 幺月儿(https://gitee.com/lulanyin) Email: inphp@qq.com
// | 该文件的开源协议以所在项目的LICENSE文件为准，请遵守开源协议要求
// +----------------------------------------------------------------------
// | 导航
// +----------------------------------------------------------------------
namespace app\cms\http\api;

use app\admin\attributes\auth;
use app\cms\helper\cache;
use app\cms\model\NavModel;
use Inphp\Core\Object\Message;

class nav
{
    /**
     * 获取导航列表
     * @param array|null $params
     * @return array
     */
    public function list(?array $params = null): array
    {
        //参数
        $params = $params ?? getClient()->get;
        //优先从缓存获取
        $cache = cache::get($params, "nav/list");
        if ($cache) {
            //缓存中不为空时，直接返回
            return $cache;
        }
        //构建查询
        $db = NavModel::emptyQuery("n");
        //父级参数
        $parentId = $params["parentId"] ?? 0;
        $parentId = is_numeric($parentId) && $parentId > 0 ? ceil($parentId) : 0;
        $db->where("n.parentId", $parentId);
        //
        $user = authUserInfo();
        //
        $admin = $params["admin"] ?? 0;
        $siteId = $params["siteId"] ?? 0;
        $siteId = is_numeric($siteId) && $siteId > 0 ? ceil($siteId) : 0;
        if (($admin != 1 || is_null($user) || $user["admin"] != 1) && $siteId <= 0) {
            //非后台获取，需要进行SITE ID处理，并且仅支持固定SITE ID
            //优先使用GET参数，再到origin，再到host
            $site = matchCMSSite();
            if (!empty($site)) {
                $siteId = $site["id"];
            }
            if ($siteId === 0) {
                return [];
            }
        }
        //$params["siteId"] = $siteId;
        $db->whereIn("n.siteId", [$siteId, 0]);
        //获取列表
        $list = $db->orderBy("n.weight", "asc")->get();
        //是否获取全部
        $all = $params["all"] ?? 1;
        $all = $all == 1;
        //遍历处理
        foreach ($list as &$item) {
            //链接处理
            if ($all) {
                $item["subList"] = $this->subList($item["id"]);
            }
        }
        //保存至缓存
        cache::set($params, $list, "nav/list");
        //返回数组
        return $list;
    }

    /**
     * 获取子导航
     * @param int $parentId
     * @return array
     */
    private function subList(int $parentId): array
    {
        $list = NavModel::emptyQuery("n")->where("n.parentId", $parentId)->orderBy("n.weight", "asc")->get();
        //遍历处理
        foreach ($list as &$item) {
            $item["subList"] = $this->subList($item["id"]);
        }
        //返回数组
        return $list;
    }

    /**
     * 保存导航列表
     * 允许传递一个列表的JSON数据，或表单数据
     * @param int $parentId
     * @param array|null $list
     * @return Message
     */
    #[auth("cms/nav")] public function saveList(int $parentId = -1, ?array $list = null): Message
    {
        $list = $list ?? POST("list");
        $list = is_array($list) ? $list : (!empty($list) ? (@json_decode($list, true) ?? []) : []);
        if (empty($list)) {
            return httpMessage("没有数据需要保存");
        }
        $siteId = POST("siteId");
        $siteId = is_numeric($siteId) && $siteId > 0 ? ceil($siteId) : 0;
        $fail = $success = 0;
        //临时用
        $parents = [];
        //遍历处理
        foreach ($list as $item) {
            if (is_array($item)) {
                $id = $item["id"] ?? 0;
                $sid = $item["siteId"] ?? 0;
                $sid = is_numeric($sid) ? ceil($sid) : 0;
                $sid = $sid > 0 ? $sid : $siteId;
                $pid = $parentId > 0 ? $parentId : ($item["parentId"] ?? 0);
                $pid = is_numeric($pid) ? ceil($pid) : 0;
                $name = $item["name"] ?? null;
                $icon = $item["icon"] ?? null;
                $weight = $item["weight"] ?? 50;
                $weight = is_numeric($weight) ? ceil($weight) : 50;
                $url = $item["url"] ?? null;
                //处理数据
                if (empty($name)) {
                    continue;
                }
                //限长
                $name = mb_strlen($name) > 25 ? mb_substr($name, 0, 25) : $name;
                $url = !empty($url) && strlen($url) > 100 ? substr($url, 0, 100) : $url;
                $db = NavModel::emptyQuery();
                $method = "insert";
                $data = [
                    "name"  => $name,
                    "icon"  => $icon,
                    "url"   => $url,
                    "weight"=> $weight
                ];
                if ($id > 0) {
                    $db->where("id", $id)->set($data);
                    $method = "update";
                } else {
                    $data["siteId"] = $sid;
                    //取父级
                    if ($pid > 0 && !isset($parents[$pid])) {
                        $parents[$pid] = NavModel::getRowByPrimaryKey($pid);
                    }
                    if (!empty($parents[$pid])) {
                        $data["parentId"] = $parents[$pid]["id"];
                        $data["parentsId"] = !empty($parents[$pid]["parentsId"]) ? "{$parents[$pid]["id"]},{$parents[$pid]["parentsId"]}" : $parents[$pid]["id"];
                        $data["siteId"] = $parents[$pid]["siteId"];
                        $data["floor"] = floor($parents[$pid]["floor"] + 1);
                    }
                }
                if (!$db->{$method}($data)) {
                    $fail++;
                } else {
                    $success += $db->getAffectRows();
                    $id = $id > 0 ? $id : $db->getLastInsertId();
                    //如果存在下级，将下级数据一并保存
                    if (isset($item["subList"])) {
                        @$this->saveList($id, $item["subList"]);
                    }
                }
            }
        }
        //清除缓存
        cache::clean("nav");
        return httpMessage(0, "已保存数据");
    }

    /**
     * 删除导航，连带下级一并删除
     * @return Message
     */
    #[auth("cms/nav")] public function delete(): Message
    {
        $id = POST("id");
        $id = is_numeric($id) && $id > 0 ? ceil($id) : 0;
        if ($id <= 0) {
            return httpMessage("ID参数无效");
        }
        //
        $db = NavModel::emptyQuery()
            ->where("id", $id)
            ->orWhereFindInSet($id, "parentsId");
        if ($db->delete()) {
            //清除缓存
            cache::clean("nav");
            return httpMessage(0, "已删除{$db->getAffectRows()}行数据");
        }
        return httpMessage("删除失败");
    }
}